/**
 *  debug.cpp
 *  AwkwardCubed - Sys
 *
 *  Date: 20/08/2013
 *
 *  Language: C++
 *
 *  @author Carl mcCaffrey
 *
 */
#include "sys/debug.h"

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif // WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <stdarg.h>
#include <string>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>

void Debug::Init(const char* filename)
{
	file.open(filename);
	file << "----------AwkwardCubed Debug File----------\n\n\n";
#ifdef _DEBUG
	// Allocate COnsole
	if(AllocConsole() != 0){
		int consoleHandle;
		long stdHandle;
		CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
		FILE* fp;

		// Set the screen buffer to let us scroll text
		GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo);
		consoleInfo.dwSize.Y = 500;
		SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), consoleInfo.dwSize);

		// Redirect STDOUT to console
		stdHandle = static_cast<long>(STD_OUTPUT_HANDLE);
		consoleHandle = _open_osfhandle(stdHandle, _O_TEXT);

		fp = _fdopen(consoleHandle, "w");
		*stdout = *fp;
		setvbuf(stdout, NULL, _IONBF, 0);

		// Redirect STDIN to console
		stdHandle = static_cast<long>(STD_INPUT_HANDLE);
		consoleHandle = _open_osfhandle(stdHandle, _O_TEXT);

		fp = _fdopen(consoleHandle, "r");
		*stdin = *fp;
		setvbuf(stdin, NULL, _IONBF, 0);

		// Redirect STDERR to console
		stdHandle = static_cast<long>(STD_ERROR_HANDLE);
		consoleHandle = _open_osfhandle(stdHandle, _O_TEXT);

		fp = _fdopen(consoleHandle, "w");
		*stderr = *fp;
		setvbuf(stderr, NULL, _IONBF, 0);
	}else{
		PrintErr(DBG_ERROR_PRIORITY_LOW, "Failed to open debug console!\n\n");
	}
#endif // _DEBUG
}

void Debug::Shutdown(void)
{
	file.flush();
	file.close();
#ifdef _DEBUG
	if(FreeConsole() == 0){
		PrintErr(DBG_ERROR_PRIORITY_LOW, "Failed to close debug console!\n\n");
	}
#endif // _DEBUG
}

void Debug::Print(char* string, ...)
{
	va_list argptr;
	char buffer[200];
	va_start(argptr, string);
	vsprintf(buffer, string, argptr);
	va_end(argptr);

	printf(buffer);
	file << buffer;
	file.flush();
}

void Debug::PrintErr(ErrorType error, char* string, ...)
{
	va_list argptr;
	char buffer[200];
	va_start(argptr, string);
	vsprintf(buffer, string, argptr);
	va_end(argptr);

	std::string result;

	switch(error){
		case DBG_ERROR_PRIORITY_LOW:
			result = "\nLow Priority Error: " + std::string(buffer);
			break;

		case DBG_ERROR_PRIORITY_MEDIUM:
			result = "\nMedium Priority Error: " + std::string(buffer);
			break;

		case DBG_ERROR_PRIORITY_HIGH:
			result = "\nHigh Priority Error: " + std::string(buffer);
			break;

		case DBG_ERROR_PRIORITY_SEVERE:
			result = "\nSEVERE ERROR: " + std::string(buffer);
			MessageBox(NULL, buffer, "AwkwardCubed: SEVERE ERROR", MB_ICONERROR | MB_OK);
			break;
	}

	printf(result.c_str());
	file << result.c_str();
	file.flush();
}

int Debug::MsgBox(const char* title, const char* text, unsigned int type)
{
	printf("MessageBox: %s\n", text);
	Print("MessageBox: %s\n", text);
	std::string string = "AwkwardCubed: " + std::string(title);
	return MessageBox(NULL, text, string.c_str(), type);
}